package com.cmlite;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.json.JSONException;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.cmlite.adapter.PeopleAdapter;
import com.cmlite.adapter.PeopleAdapter.OnCBClickListListener;
import com.cmlite.adapter.PeopleAdapter.OnClickListListener;
import com.cmlite.adapter.PeopleAdapter.OnLongClickListListener;
import com.cmlite.base.BaseActivity;
import com.cmlite.base.BaseInit;
import com.cmlite.component.ClearableEditText;
import com.cmlite.component.ClearableEditText.Listener;
import com.cmlite.connect.AsyncTask_Api;
import com.cmlite.connect.AsyncTask_ApiListener;
import com.cmlite.connect.CallApi;
import com.cmlite.connect.HTTPReq;
import com.cmlite.connect.ScreenStopper;
import com.cmlite.model.OutResult;
import com.cmlite.model.PeopleModel;
import com.cmlite.model.PeopleModelList;
import com.cmlite.util.ConnectionException;
import com.cmlite.util.EmptyDataException;
import com.cmlite.util.SharedPreferencesDB;
import com.cmlite.util.SideBar;
import com.cmlite.util.TokenUnableException;
import com.cmlite.util.Util;

@SuppressLint("DefaultLocale")
public class A004ListPeople extends BaseActivity implements BaseInit,
		OnClickListener, AsyncTask_ApiListener, TextWatcher, Listener {

	public static final int RESULT_LOGOUT = 1;
	public static final int RESULT_A005 = 0;
	public static final int TYPE_GET = 0;
	public static final int TYPE_UPDATE = 1;
	private static final int TYPE_DELETE = 3;
	private static final int TYPE_LOGOUT = 4;

	private static final int ADD_PEOPLE = 1;
	private static final int EDIT_PEOPLE = 2;
	private static final String TAG = A004ListPeople.class.getName();

	private String mEventId;
	private String mEventName;

	private PeopleModel mPeopleDel;

	private int index = 1;

	private ClearableEditText et_search;
	private ListView mListView;
	private TextView tv_title_header, btn_logout, btn_add, btn_refresh,
			btn_back;
	private TextView tv_sort_firstname, tv_sort_lastname, tv_sort_field_01,
			tv_sort_field_02, tv_sort_field_03, tv_sort_checkbox;
	private RelativeLayout a004_layout_listview;
	private LinearLayout a004_footer_layout_right;
	private SideBar mSideBar;
	private String[] labels;
	private String[] keys;
	HashMap<String, String> hashMapKeySync;
	private int positionSelection = 0;
	
	private Parcelable state;

	private PeopleAdapter mAdapter;
	private PeopleModelList mPeopleList;
    private String token;
	private Handler mHandler = new Handler();

	private HashMap<String, List<PeopleModel>> dictDisplay;

	@Override
	public void onIOnCreate(Bundle savedInstanceState) {
		initView();
	}

	@Override
	public void onIRestart() {

	}

	@Override
	public void onIStart() {

	}

	@Override
	public void onIResume() {

	}

	@Override
	public void onIDestroy() {
		onLogout(token);
		Log.d(TAG, "Destroy !!!!!");

	}

	@Override
	public void onIActivityResult(int requestCode, int resultCode, Intent data) {
		try {
			if (resultCode == RESULT_A005) { // add people
				if (data.getExtras() != null) {
					final int type = data.getExtras().getInt("type");
					final String[] mArr = data.getExtras().getStringArray(
							"params");
					final PeopleModel p = new PeopleModel(mArr[0], mArr[1],
							mArr[2], mArr[3], mArr[4], mArr[5], mArr[6]);

					Log.d("SON", "RESULT_A005: " + p.toString());

					if (type == 1) // add
					{
						mPeopleList.addItem(p);
					} else if (type == 2) { // update
						// update
						mPeopleList.updateItem(p, type);
					}
					updateListView(mPeopleList.getmPeopleEvent(), null);
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	public void onIBackPressed() {
		// TODO Auto-generated method stub

	}

	@Override
	public void initView() {
		// TODO Auto-generated method stub
		setContentView(R.layout.a004listpeople);

		this.a004_layout_listview = (RelativeLayout) findViewById(R.id.a004_layout_listview);
		this.et_search = (ClearableEditText) findViewById(R.id.a004_et_search);
		this.et_search.setListener(this);
		this.mListView = (ListView) findViewById(R.id.a004_listview);
		this.mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

		final View v_footer = (View) findViewById(R.id.a004_footer);
		this.btn_logout = (TextView) v_footer.findViewById(R.id.footer_tv_back);
		this.btn_logout.setVisibility(View.VISIBLE);
		this.a004_footer_layout_right = (LinearLayout) v_footer
				.findViewById(R.id.footer_layout_right);
		this.a004_footer_layout_right.setVisibility(View.VISIBLE);
		this.btn_add = (TextView) v_footer.findViewById(R.id.footer_tv_next_01);
		this.btn_refresh = (TextView) v_footer
				.findViewById(R.id.footer_tv_next_02);

		final View v_header = (View) findViewById(R.id.a004_header);
		this.tv_title_header = (TextView) v_header
				.findViewById(R.id.header_tv_title);
		this.btn_back = (TextView) v_header.findViewById(R.id.header_tv_back);
		this.btn_back.setVisibility(View.VISIBLE);

		this.mSideBar = (SideBar) findViewById(R.id.a004_sidebar);

		final View v_header_listview = (View) findViewById(R.id.a004_layout_header_listview);
		this.tv_sort_firstname = (TextView) v_header_listview
				.findViewById(R.id.header_listview_tv_firstname);
		this.tv_sort_lastname = (TextView) v_header_listview
				.findViewById(R.id.header_listview_tv_lastname);
		this.tv_sort_field_01 = (TextView) v_header_listview
				.findViewById(R.id.header_listview_tv_field01);
		this.tv_sort_field_02 = (TextView) v_header_listview
				.findViewById(R.id.header_listview_tv_field02);
		this.tv_sort_field_03 = (TextView) v_header_listview
				.findViewById(R.id.header_listview_tv_field03);
		this.tv_sort_checkbox = (TextView) v_header_listview
				.findViewById(R.id.header_listview_tv_checkbox);

		this.et_search.addTextChangedListener(this);
		this.btn_back.setOnClickListener(this);
		this.btn_logout.setOnClickListener(this);
		this.btn_add.setOnClickListener(this);
		this.btn_refresh.setOnClickListener(this);
		this.tv_sort_firstname.setOnClickListener(this);
		this.tv_sort_lastname.setOnClickListener(this);
		this.tv_sort_field_01.setOnClickListener(this);
		this.tv_sort_field_02.setOnClickListener(this);
		this.tv_sort_field_03.setOnClickListener(this);
		this.tv_sort_checkbox.setOnClickListener(this);

		Bundle b = getIntent().getExtras();
		this.mEventId = b.getString("mId");
		this.mEventName = b.getString("mTitle");
		if (mEventName != null)
			this.tv_title_header.setText(mEventName);

		tv_sort_firstname.setSelected(true);
		btn_back.setText(mRes.getString(R.string.events));

		initData();
	}

	@Override
	public void initData() {
		dictDisplay = new HashMap<String, List<PeopleModel>>();
		hashMapKeySync = new HashMap<String, String>();
		getPeopleList();
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.header_tv_back:
			finish();
			break;
		case R.id.footer_tv_back:
			 SharedPreferencesDB db = new SharedPreferencesDB(this);
			 token = db.getPrefToken();
			 callBackLogin("");

			break;
		case R.id.footer_tv_next_01: // refresh
			callSyncPeople();
			break;
		case R.id.footer_tv_next_02: // add
			callPeople(ADD_PEOPLE, null);
			break;
		// SORT
		case R.id.header_listview_tv_firstname:
			index = 1;
			updateListView(mPeopleList.getmPeopleEvent(), null);
			updateTextHeaderListView();
			break;
		case R.id.header_listview_tv_lastname:
			index = 2;
			updateListView(mPeopleList.getmPeopleEvent(), null);
			updateTextHeaderListView();
			break;
		case R.id.header_listview_tv_field01:
			index = 3;
			updateListView(mPeopleList.getmPeopleEvent(), null);
			updateTextHeaderListView();
			break;
		case R.id.header_listview_tv_field02:
			index = 4;
			updateListView(mPeopleList.getmPeopleEvent(), null);
			updateTextHeaderListView();
			break;
		case R.id.header_listview_tv_field03:
			index = 5;
			updateListView(mPeopleList.getmPeopleEvent(), null);
			updateTextHeaderListView();
			break;
		case R.id.header_listview_tv_checkbox:
			break;
		default:
			break;
		}
	}

	private void onLogout(final String token) {
		if (Util.getNetworkStatus(getApplicationContext())) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						HTTPReq htreq = new HTTPReq(CallApi.SERVER);
						String format = String.format("/logout/%s", token);
						HashMap<String, String> hashMap = new HashMap<String, String>();
						htreq.post(getApplicationContext(), format, hashMap);
					} catch (EmptyDataException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (ConnectionException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (TokenUnableException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}
			}).run();

		} else {
			Util.showDialog(getApplicationContext(), R.string.warning,
					R.string.network_not_available, R.drawable.exclamation);
		}
	}

	private void updateTextHeaderListView() {
		et_search.setText("");
		switch (index) {
		case 1:
			tv_sort_firstname.setSelected(true);
			tv_sort_lastname.setSelected(false);
			tv_sort_field_01.setSelected(false);
			tv_sort_field_02.setSelected(false);
			tv_sort_field_03.setSelected(false);
			break;
		case 2:
			tv_sort_firstname.setSelected(false);
			tv_sort_lastname.setSelected(true);
			tv_sort_field_01.setSelected(false);
			tv_sort_field_02.setSelected(false);
			tv_sort_field_03.setSelected(false);
			break;
		case 3:
			tv_sort_firstname.setSelected(false);
			tv_sort_lastname.setSelected(false);
			tv_sort_field_01.setSelected(true);
			tv_sort_field_02.setSelected(false);
			tv_sort_field_03.setSelected(false);
			break;
		case 4:
			tv_sort_firstname.setSelected(false);
			tv_sort_lastname.setSelected(false);
			tv_sort_field_01.setSelected(false);
			tv_sort_field_02.setSelected(true);
			tv_sort_field_03.setSelected(false);
			break;
		case 5:
			tv_sort_firstname.setSelected(false);
			tv_sort_lastname.setSelected(false);
			tv_sort_field_01.setSelected(false);
			tv_sort_field_02.setSelected(false);
			tv_sort_field_03.setSelected(true);
			break;
		default:
			break;
		}
	}

	private void callPeople(int type, PeopleModel people) {
		try {
			Intent i = new Intent(mContext, A005AddPeople.class);
			i.putExtra("type", type);
			i.putExtra("people", people);
			i.putExtra("labels", labels);
			i.putExtra("event_id", mEventId);

			i.putExtra("event_name", mEventName);
			i.putExtra("keys", keys);
			startActivityForResult(i, RESULT_A005);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public void updateListView(List<PeopleModel> data, String search) {
		dictDisplay.clear();
		Collections.sort(data, new Comparator<PeopleModel>() {
			@Override
			public int compare(PeopleModel lhs, PeopleModel rhs) {
				return lhs.getValueByIndex(index).compareTo(
						rhs.getValueByIndex(index));
			}
		});
		List<PeopleModel> peoples = new ArrayList<PeopleModel>();
		boolean isColor = true;
		if (search != null) {
			for (PeopleModel people : data) {
				if (people.getValueByIndex(index).toLowerCase()
						.matches(search.toLowerCase())) {
					String value = people.getValueByIndex(index).trim();
					String key = value.substring(0, 1).toUpperCase();
					List<PeopleModel> values = dictDisplay.get(key);
					if (values == null) {
						values = new ArrayList<PeopleModel>();
						final PeopleModel p = new PeopleModel();
						p.setmField_01(key);
						// System.out.println("KEY: " + key);
						p.setGroup(true);
						peoples.add(p);
						dictDisplay.put(key, values);
					}
					people.setColor(isColor);
					isColor = !isColor;
					values.add(people);
					peoples.add(people);
				}
			}
		} else {
			for (PeopleModel people : data) {
				String value = people.getValueByIndex(index).trim();
				String key = value.substring(0, 1).toUpperCase();
				List<PeopleModel> values = dictDisplay.get(key);
				if (values == null) {
					values = new ArrayList<PeopleModel>();
					final PeopleModel p = new PeopleModel();
					p.setmField_01(key);
					// System.out.println("KEY: " + key);
					p.setGroup(true);
					peoples.add(p);
					dictDisplay.put(key, values);
				}
				people.setColor(isColor);
				isColor = !isColor;
				values.add(people);
				peoples.add(people);
			}
		}
		mAdapter = new PeopleAdapter(mContext, R.layout.item_people, peoples,
				listenerClick, listenerCBClick, listenerLongClick);
		mListView.setAdapter(mAdapter);
		mListView.onRestoreInstanceState(state);
		Set<String> key1 = dictDisplay.keySet();
		Set<String> key = new TreeSet<String>(key1);
		char[] l = new char[key.size()];
		Iterator<String> iter = key.iterator();
		int i = 0;
		while (iter.hasNext()) {
			l[i] = iter.next().charAt(0);
			// System.out.println("i: " + i + " - " + l[i]);
			i++;
		}
		if (l.length > 0) {
			mSideBar.setVisibility(View.VISIBLE);
			mSideBar.setListView(mListView, a004_layout_listview, l);
		} else {
			mSideBar.setVisibility(View.GONE);
		}
		updateField05();
	}

	private void getPeopleList() {
		try {
			positionSelection = this.mListView.getFirstVisiblePosition();
			state = mListView.onSaveInstanceState();
			if (Util.getNetworkStatus(mContext)) {
				AsyncTask_Api apiTask = new AsyncTask_Api(this, this, TYPE_GET,
						0, ScreenStopper.STYLE_PROGRESS_PROCESS);
				apiTask.execute();
			} else {
				Util.showDialog(this, R.string.warning,
						R.string.network_not_available, R.drawable.exclamation);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	public Object callApi(int serachType, Object apidata) {
		// TODO Auto-generated method stub
		if (serachType == TYPE_GET) {
			try {
				SharedPreferencesDB db = new SharedPreferencesDB(this);
				return CallApi.getPeopleListOfEvent(mContext,
						db.getPrefToken(), mEventId, 25, 0, null, null, null);
			} catch (EmptyDataException e) {
				e.printStackTrace();
			} catch (ConnectionException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (TokenUnableException e) {
				callBackLogin(e.getMessage());
			}
		} else if (serachType == TYPE_UPDATE) {
			try {
				SharedPreferencesDB db = new SharedPreferencesDB(this);
				return CallApi.getPeopleListOfEvent(mContext,
						db.getPrefToken(), mEventId, hashMapKeySync);
			} catch (EmptyDataException e) {
				e.printStackTrace();
			} catch (ConnectionException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (TokenUnableException e) {
				callBackLogin(e.getMessage());
			}
		} else if (serachType == TYPE_DELETE) {
			try {
				SharedPreferencesDB db = new SharedPreferencesDB(this);
				return CallApi.deletePeople(mContext, db.getPrefToken(),
						mEventId, mPeopleDel.getmPeople_ID(), keys, labels);
			} catch (EmptyDataException e) {
				e.printStackTrace();
			} catch (ConnectionException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (TokenUnableException e) {
				callBackLogin(e.getMessage());
			}
		} else if (serachType == TYPE_LOGOUT) {
			try {
				SharedPreferencesDB db = new SharedPreferencesDB(this);
				return CallApi.postLogout(mContext, db.getPrefToken());
			} catch (EmptyDataException e) {
				e.printStackTrace();
			} catch (ConnectionException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (TokenUnableException e) {
				callBackLogin(e.getMessage());
			}
		}
		return null;
	}

	private void callBackLogin(String message) {
		Intent i = new Intent(this, A1002Login.class);
		i.putExtra("message", message);
		setResult(1, i);
		finish();
	}

	@Override
	public void finishApi(int serachType, Object apiresult) {
		try {
			if (serachType == TYPE_GET) {
				initPeopleList();
				mPeopleList = (PeopleModelList) apiresult;
				labels = mPeopleList.lables;
				keys = mPeopleList.key;
				updateHeaderListView(labels);
				updateListView(mPeopleList.getmPeopleEvent(), null);
			} else if (serachType == TYPE_UPDATE) {
				Log.d(TAG, "Finish Synch peoples complete !!!");
				OutResult out = (OutResult) apiresult;
				if (out != null) {
					if (out.getStatus() && out.getCode() == 200) {
						if (hashMapKeySync != null)
							hashMapKeySync.clear();
						getPeopleList();
					}
				}
			} else if (serachType == TYPE_DELETE) {
				OutResult out = (OutResult) apiresult;
				if (out != null) {
					if (out.getStatus() && out.getCode() == 200) {
						mPeopleList.getmPeopleEvent().remove(mPeopleDel);
						mPeopleDel = null;
						updateListView(mPeopleList.getmPeopleEvent(), null);
					}
				}
			}
		} catch (Exception ex) {

		}
	}

	@Override
	public void tokenExpride() {
		// TODO Auto-generated method stub

	}

	// @Override
	// public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
	// long arg3) {
	// // TODO Auto-generated method stub
	// final PeopleModel mPeople = mPeopleList.getmPeopleEvent().get(arg2);
	// if (!mPeople.isGroup()) {
	// Log.e("SON", "LongClick: " + arg2);
	// position = arg2;
	// mListViewItemLongClick(mPeople);
	// return true;
	// }
	// return false;
	// }

	private void mListViewItemLongClick(final PeopleModel people) {
		AlertDialog a = new AlertDialog.Builder(mContext)
				// .setTitle(context.getString(R.string.msg_bookmark_sync)).
				.setTitle(R.string.title_people)
				.setCancelable(false)
				.setItems(R.array.people_name_array,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog2,
									final int which) {
								switch (which) {
								case 0:
									callPeople(EDIT_PEOPLE, people);
									break;
								case 1:
									mPeopleDel = people;
									callDeletePeople();
									break;
								default:
									break;
								}
							}
						}).create();

		a.show();
	}

	private void updateField05() {
		if (mPeopleList != null && mPeopleList.getmPeopleEvent().size() > 0)
			tv_sort_checkbox.setText(mPeopleList.getCountCheck() + "/"
					+ mPeopleList.getSize());
		else
			tv_sort_checkbox.setText("0/0");
	}

	private void updateHeaderListView(String[] labels) {
		tv_sort_firstname.setText(labels[0]);
		tv_sort_lastname.setText(labels[1]);
		tv_sort_field_01.setText(labels[2]);
		tv_sort_field_02.setText(labels[3]);
		tv_sort_field_03.setText(labels[4]);

	}

	private void initPeopleList() {
		if (mPeopleList != null) {
			mPeopleList.getmPeopleEvent().clear();
			mPeopleList = null;
		}
		mPeopleList = new PeopleModelList();
	}

	private OnClickListListener listenerClick = new OnClickListListener() {

		@Override
		public void onClick(PeopleModel data) {
			// data.setCheck(!data.isCheck());
			getIdKeyCheck(data);
			updateField05();
		}
	};

	private OnCBClickListListener listenerCBClick = new OnCBClickListListener() {
		@Override
		public void onClick(PeopleModel data) {
			// data.setCheck(!data.isCheck());
			getIdKeyCheck(data);
			updateField05();
		}
	};

	private OnLongClickListListener listenerLongClick = new OnLongClickListListener() {
		@Override
		public void onLongClick(View v, PeopleModel data, int position) {
			mListViewItemLongClick(data);

			((PeopleAdapter) mListView.getAdapter()).notifyDataSetChanged();
			mHandler.postDelayed(new Runnable() {

				@Override
				public void run() {
					// call any new activity here or do any thing you want here

				}
			}, 100);
		}
	};

	private void callSyncPeople() {
		if (Util.getNetworkStatus(mContext)) {
			AsyncTask_Api apiTask = new AsyncTask_Api(this, this, TYPE_UPDATE,
					0, ScreenStopper.STYLE_PROGRESS_PROCESS);
			apiTask.execute();
		} else {
			Util.showDialog(mContext, R.string.warning,
					R.string.network_not_available, R.drawable.exclamation);
		}
	}

	private void callDeletePeople() {
		if (Util.getNetworkStatus(mContext)) {
			AsyncTask_Api apiTask = new AsyncTask_Api(this, this, TYPE_DELETE,
					0, ScreenStopper.STYLE_PROGRESS_PROCESS);
			apiTask.execute();
		} else {
			Util.showDialog(mContext, R.string.warning,
					R.string.network_not_available, R.drawable.exclamation);
		}
	}

	@Override
	public void afterTextChanged(Editable arg0) {
		// TODO Auto-generated method stub
		if (arg0.toString().trim().length() > 0) {
			final String search = ".*" + arg0.toString().trim() + ".*";
			updateListView(mPeopleList.getmPeopleEvent(), search);
		}
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// TODO Auto-generated method stub
	}

	private void getIdKeyCheck(PeopleModel people) {
		for (PeopleModel p : mPeopleList.getmPeopleEvent()) {
			if (p.getmPeople_ID().equalsIgnoreCase(people.getmPeople_ID())) {
				if (!p.isCheck()) { // people in list is not checked.
					p.setCheck(true);
					hashMapKeySync.put("peoples[" + people.getmPeople_ID()
							+ "]", "1");
				} else {
					p.setCheck(false);
					hashMapKeySync.put("peoples[" + people.getmPeople_ID()
							+ "]", "0");
				}
				Log.e(TAG, "Select People[ id : " + people.getmPeople_ID()
						+ "][checked : " + people.isCheck() + "]");
				break;
			}
		}
	}

	@Override
	public void didClearText() {
		// TODO Auto-generated method stub
		updateListView(mPeopleList.getmPeopleEvent(), null);
	}
}
